﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.Prism.Commands;
using System.Windows.Input;
namespace Module.Event
{
    class TextBoxBehavior
    {
        private static DependencyProperty _property;
        private static readonly RoutedEvent _lostFocusEvent = TextBox.LostFocusEvent;
        private static readonly RoutedEvent _keyUpEvent = TextBox.KeyUpEvent;

        public static readonly DependencyProperty IsFocusedProperty = 
            DependencyProperty.RegisterAttached("IsFocused",
            typeof(bool), typeof(TextBoxBehavior),
               new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));

        public static readonly DependencyProperty LostFocusCommandProperty =
            DependencyProperty.RegisterAttached("LostFocusCommand",
            typeof(ICommand), typeof(TextBoxBehavior),
            new PropertyMetadata(LostFocusCallBack));

        public static readonly DependencyProperty TextChangeCommandProperty =
           DependencyProperty.RegisterAttached("TextChangeCommand",
           typeof(ICommand), typeof(TextBoxBehavior),
           new PropertyMetadata(TextChangeCallBack)); 

        public static void SetLostFocusCommand(UIElement obj, DelegateCommand value)
        {
            obj.SetValue(LostFocusCommandProperty, value);
        }

        public static void SetTextChangeCommand(UIElement obj, DelegateCommand value)
        {
            obj.SetValue(TextChangeCommandProperty, value);
        }

        static void LostFocusCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            UIElement element = obj as UIElement;

            _property = args.Property;

            if (element != null)
            {
                if (args.OldValue != null)
                {
                    element.AddHandler(_lostFocusEvent, new RoutedEventHandler(EventHandler));
                    element.AddHandler(_keyUpEvent, new RoutedEventHandler(EventHandler));
                }

                if (args.NewValue != null)
                {                    
                    element.AddHandler(_lostFocusEvent, new RoutedEventHandler(EventHandler));
                    element.AddHandler(_keyUpEvent, new RoutedEventHandler(EventHandler));
                    element.AddHandler(RichTextBox.KeyUpEvent, new RoutedEventHandler(EventHandler));
                }
            }
        }

        static void TextChangeCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            UIElement element = obj as UIElement;

            _property = args.Property;

            if (element != null)           
            {
               
                if (args.NewValue != null)
                {           
                    element.AddHandler(TextBox.TextChangedEvent, new RoutedEventHandler(TextChangeEventHandler));
                }
            }
        }

        public static void EventHandler(object sender, RoutedEventArgs e)
        {
            
            DependencyObject obj = sender as DependencyObject;            
            if (obj != null)
            {
                ICommand icommand = obj.GetValue(_property) as ICommand;

                if (icommand != null)
                {
                    if ((e.RoutedEvent != Keyboard.KeyUpEvent) || ((e.RoutedEvent == Keyboard.KeyUpEvent) 
                        && ((e as KeyEventArgs).Key == Key.Enter)))
                    {
                        DelegateCommand<object> command = icommand as DelegateCommand<object>;
                        if (command.CanExecute(sender))
                            command.Execute(sender);
                    }
                }
            }
        }

        public static void TextChangeEventHandler(object sender, RoutedEventArgs e)
        {
            DependencyObject obj = sender as DependencyObject;
            if (obj != null)
            {
                ICommand icommand = obj.GetValue(_property) as ICommand;

                if (icommand != null)
                { 
                    DelegateCommand<object> command = icommand as DelegateCommand<object>;
                    if (command.CanExecute(sender))
                        command.Execute(sender);
                   
                }
            }
        }




        static void OnIsFocusedPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            TextBox element = obj as TextBox;

            if (args.NewValue != null)
            {
                element.Focus();
                element.SelectAll();
            }
        }


        public static bool GetIsFocused(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsFocusedProperty);
        }


        public static void SetIsFocused(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFocusedProperty, value);
        }
      }
}
